package com.cloud.log.autolevel.service.impl;

import com.cloud.log.autolevel.service.LogLevelSettingService;
import com.cloud.log.autolevel.bean.LoggerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggingSystem;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.slf4j.Logger.ROOT_LOGGER_NAME;

/**
 * @author: ZhangKaiQiang
 * @date: 2020/12/29
 * @time: 14:11
 **/
public class LogLevelSettingServiceImpl implements LogLevelSettingService {

    private final LoggingSystem loggingSystem;

    private Logger logger= LoggerFactory.getLogger(LogLevelSettingServiceImpl.class);


    public LogLevelSettingServiceImpl(LoggingSystem loggingSystem){
        this.loggingSystem=loggingSystem;
    }

    @Override
    public void setRootLoggerLevel(String level) {
        LoggerConfiguration loggerConfiguration = loggingSystem.getLoggerConfiguration(ROOT_LOGGER_NAME);

        if (loggerConfiguration==null){
          if (logger.isErrorEnabled()){
              logger.error("no loggerConfiguration with loggerName"+level);
          }
          return;
        }

        // 判断设置的日志级别是否合理
        if (!supportLevels().contains(level)){
            if (logger.isErrorEnabled()){
                logger.error("current Level is not support"+level);
            }
            return;
        }

        // 判断当前生效的日志级别
        if (!loggerConfiguration.getEffectiveLevel().equals(LogLevel.valueOf(level))){
            if (logger.isInfoEnabled()) {
                logger.info("set RootLoggerLevel success,old level is  '" + loggerConfiguration.getEffectiveLevel()
                        + "' , new level is '" + level + "'");
            }
            loggingSystem.setLogLevel(ROOT_LOGGER_NAME, LogLevel.valueOf(level));
        }
    }

    @Override
    public void setLoggerLevel(List<LoggerConfig> configList) {
        Optional.ofNullable(configList).orElse(Collections.emptyList()).forEach(loggerConfig -> {

            LoggerConfiguration loggerConfiguration = loggingSystem.getLoggerConfiguration(loggerConfig.getLoggerName());
            if (loggerConfiguration==null){
                if (logger.isErrorEnabled()){
                    logger.error("no loggerConfiguration with loggerName"+loggerConfig.getLoggerName());
                }
            }

            if (!supportLevels().contains(loggerConfig.getLevel())){
                if (logger.isErrorEnabled()){
                    logger.error("current Level is not support"+loggerConfig.getLevel());
                }
            }

            loggingSystem.setLogLevel(loggerConfig.getLoggerName(),LogLevel.valueOf(loggerConfig.getLevel()));
            if (logger.isInfoEnabled()){
                logger.info("update "+loggerConfig.getLoggerName()+" level to "+loggerConfig.getLevel());
            }

        });
    }


    private List<String> supportLevels() {
        return loggingSystem.getSupportedLogLevels().stream().map(Enum::name).collect(Collectors.toList());
    }
}
